package yartiss.service.model;

import java.util.HashMap;
import java.util.Map;

import javax.swing.BoundedRangeModel;
import javax.swing.DefaultBoundedRangeModel;

import org.jfree.data.category.DefaultCategoryDataset;

import yartiss.engine.simulation.IEnergyProfile;
import yartiss.engine.simulation.SimulationStatistics;

public class Scenario {
	
	private final long simulationDuration;
	private final String scenarioName;
	private long systemsCount;
	private final Map<String, Integer> nbReceivedByPolicy = new HashMap<String, Integer>();
	private final Map<String, SimulationStatistics> policiesStats = new HashMap<String, SimulationStatistics>();
	private final DefaultCategoryDataset data = new DefaultCategoryDataset();
	private final BoundedRangeModel progressModel = new DefaultBoundedRangeModel(0, 1, 0, 100000);
	private final TasksSetsTableModel setsModel = new TasksSetsTableModel();
	private final IEnergyProfile profile;
	
	public Scenario(IEnergyProfile profile, long simDuaration){
		this.profile = profile;
		scenarioName =profile.getMaxEnergyLevel()+"_"+profile.getPowerRate();
		simulationDuration = simDuaration;
	}
	
	public void updatePolicyStats(String policyName, SimulationStatistics newStats){
		
		SimulationStatistics stat = policiesStats.containsKey(policyName) ? policiesStats.get(policyName) : new SimulationStatistics();
		int nbReceived = nbReceivedByPolicy.containsKey(policyName) ? nbReceivedByPolicy.get(policyName)+1 : 1 ;
		
		
		
		stat.setTimePassedWithEmax(stat.getTimePassedWithEmax()	+ newStats.getTimePassedWithEmax());
		stat.setTimePassedWithEmin(stat.getTimePassedWithEmin()	+ newStats.getTimePassedWithEmin());
		stat.setSimulationDuration(stat.getSimulationDuration()	+ newStats.getSimulationDuration());
		stat.setAverageBusyPeriod(stat.getAverageBusyPeriod()	+ newStats.getAverageBusyPeriod());
		stat.setAverageIdlePeriod(stat.getAverageIdlePeriod()	+ newStats.getAverageIdlePeriod());
		stat.setFailureCount(stat.getFailureCount()		+ newStats.getFailureCount());

		getData().setValue(stat.getFailureCount(), "Failure", policyName);
		getData().setValue((stat.getSimulationDuration() * 100)	/ (getSimulationDuration() * nbReceived), "sim duration", policyName);
		getData().setValue((stat.getAverageBusyPeriod()* 100)    / (getSimulationDuration() * nbReceived), "BP", policyName);
		getData().setValue((stat.getAverageIdlePeriod()* 100)    / (getSimulationDuration() * nbReceived), "IP", policyName);
		getData().setValue((stat.getTimePassedWithEmax() * 100)	/ (getSimulationDuration() * nbReceived), "Tmax", policyName);
		getData().setValue((stat.getTimePassedWithEmin() * 100)	/ (getSimulationDuration() * nbReceived), "Tmin", policyName);
		
		if(nbReceived == getSystemsCount()){
			stat.setAverageBusyPeriod((stat.getAverageBusyPeriod()* 100)    / (getSimulationDuration() * getSystemsCount()));
			stat.setAverageIdlePeriod((stat.getAverageIdlePeriod()* 100)    / (getSimulationDuration() * getSystemsCount()));
			stat.setSimulationDuration((stat.getSimulationDuration() * 100)	/ (getSimulationDuration() * getSystemsCount()));
			stat.setTimePassedWithEmax((stat.getTimePassedWithEmax() * 100)	/ (getSimulationDuration() * getSystemsCount()));
			stat.setTimePassedWithEmin((stat.getTimePassedWithEmin() * 100)	/ (getSimulationDuration() * getSystemsCount()));
			System.out.println(stat);
		}
		policiesStats.put(policyName, stat);
		nbReceivedByPolicy.put(policyName, nbReceived);
		
		progressModel.setMaximum((int) systemsCount*policiesStats.size());
		int newValue = 0;
		for (int val : nbReceivedByPolicy.values()) {
			newValue += val;
 		}
		progressModel.setValue(newValue);
	}

	/**
	 * @return the scenarioName
	 */
	public String getScenarioName() {
		return scenarioName;
	}

	/**
	 * @return the data
	 */
	public DefaultCategoryDataset getData() {
		return data;
	}

	/**
	 * @return the systemsCount
	 */
	public long getSystemsCount() {
		return systemsCount;
	}

	/**
	 * @param systemsCount the systemsCount to set
	 */
	public void setSystemsCount(long systemsCount) {
		this.systemsCount = systemsCount;
		
	}

	/**
	 * @return the simulationDuration
	 */
	public long getSimulationDuration() {
		return simulationDuration;
	}

	/**
	 * @return the progressModel
	 */
	public BoundedRangeModel getProgressModel() {
		return progressModel;
	}

	/**
	 * @return the setsModel
	 */
	public TasksSetsTableModel getSetsModel() {
		return setsModel;
	}

	/**
	 * @return the profile
	 */
	public IEnergyProfile getProfile() {
		return profile;
	}

}
